package com.molichuxing.services.business.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.utils.ObjectCastUtil;
import com.molichuxing.services.business.dto.request.create.PaymentBizCreateDto;
import com.molichuxing.services.business.dto.request.modify.AioPayResultBizModifyDto;
import com.molichuxing.services.business.dto.response.*;
import com.molichuxing.services.business.service.PaymentBizService;
import com.molichuxing.services.infrastructure.convertor.Convert;
import com.molichuxing.services.infrastructure.dto.request.create.PaymentCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.PaymentDetailCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.PaymentHistoryCreateDto;
import com.molichuxing.services.infrastructure.dto.request.modify.PaymentModifyDto;
import com.molichuxing.services.infrastructure.dto.response.*;
import com.molichuxing.services.infrastructure.service.*;
import com.molichuxing.services.property.*;
import com.molichuxing.services.property.sdk.WechatpayTradeTypeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 支付组合
 * </p>
 *
 * @author zhaopenghui
 * @since 2019-08-21
 */

@Service("paymentBizService")
public class PaymentBizServiceImpl implements PaymentBizService {
    private static final Logger logger = LoggerFactory.getLogger(PaymentBizServiceImpl.class);

    @Value("${profiles.active}")
    private String PROFILES_ACTIVE;

    @Value("${profiles.active.explain}")
    private String PROFILES_ACTIVE_EXPLAIN;

    @Resource
    private PaymentService paymentService;

    @Resource
    private PaymentDetailService paymentDetailService;

    @Resource
    private OfflineService offlineService;

    @Resource
    private PaymentHistoryService paymentHistoryService;

    @Resource
    private AiopayService aiopayService;

    @Resource
    private WechatpayService wechatpayService;

    @Resource
    private AlipayService alipayService;

    @Resource
    private UnionpayService unionpayService;

    /**
     * 分页查询
     *
     * @param params   key:businessType Integer 业务类型（1：订阅，2：专属：3：经销商）
     *                 key:orderCode Long 订单号
     *                 key:thirdPayNumber String 付款流水号
     *                 key:userId Integer 用户id
     *                 key:startPayTime LocalDateTime 付款开始时间
     *                 key:endPayTime LocalDateTime 付款结束时间
     *                 key:payWay Integer 支付方式
     *                 key:payType 支付类型（1：订购，2：加购，3：结算，4：还款）
     * @param pageNum
     * @param pageSize
     * @return
     * @throws Exception
     */
    @Override
    public Paged<PaymentBizDto> getPaymentPage(Map<String, Object> params, Integer pageNum, Integer pageSize)
            throws Exception {
        Paged<PaymentBizDto> result = new Paged<>(new ArrayList<>(), 0, pageSize);
        params.put("status", PaymentStatusEnum.SUCCESS_PAYMENT.getValue());
        Integer costType = ObjectCastUtil.castInteger(params.get("payType"));
        if (costType != null && costType == PaymentCostTypeEnum.SUBSCRIBE.getValue()) {
            params.put("payTypeList",
                    Arrays.asList(PaymentCostTypeEnum.SUBSCRIBE.getValue(), PaymentCostTypeEnum.RENEW.getValue()));
            params.remove("payType");
        }

        Paged<PaymentDto> paymentDtoPage = paymentService.getPaymentPage(params, pageNum, pageSize);
        // 判断是否查询为空
        if (paymentDtoPage == null) {
            return result;
        } else if (paymentDtoPage.isEmpty()) {
            return result.setTotal(paymentDtoPage.getTotal()).setTab(paymentDtoPage.getTab());
        }

        result.setTotal(paymentDtoPage.getTotal()).setTab(paymentDtoPage.getTab());

        PaymentBusinessTypeEnum businessType = PaymentBusinessTypeEnum
                .getEnum(ObjectCastUtil.castInteger(params.get("businessType")));
        for (PaymentDto paymentDto : paymentDtoPage.getList()) {
            PaymentBizDto paymentBizDto = Convert.toPaymentBizDto(paymentDto);
            if (businessType.equals(PaymentBusinessTypeEnum.DEALER)) {
                // 经销商支付信息，查询付款方信息（从线下支付表查，第三方流水号即线下支付流水编号）
                List<Integer> list = new ArrayList<>();
                list.add(OfflineAuditStatusEnum.APPROVE.getValue());
                OfflineDto offlineDto = offlineService.getOffline(paymentDto.getThirdPayNumber(), list);
                if (offlineDto == null) {
                    continue;
                }
                // 付款人
                paymentBizDto.setPayName(offlineDto.getPayName());
                // 付款银行账号
                paymentBizDto.setPayBankAccount(offlineDto.getPayBankAccount());
            } else {
                // 用户支付信息，查询保证金信息，金额减去保证金
                PaymentDetailDto paymentDetailDto = paymentDetailService.getPaymentDetail(paymentDto.getId(),
                        PaymentDetailTypeEnum.DEPOSIT);
                if (paymentDetailDto != null) {
                    paymentBizDto.setPayAmount(paymentBizDto.getPayAmount().subtract(paymentDetailDto.getAmount()));
                }
            }

            result.getList().add(paymentBizDto);
        }

        return result;
    }

    /**
     * 保证金查询
     *
     * @param params   key:orderCode Long 订单号
     *                 key:thirdPayNumber String 付款流水号
     *                 key:userId Integer 用户id
     *                 key:payWay Integer 支付方式
     *                 key:startPayTime LocalDateTime 付款开始时间
     *                 key:endPayTime LocalDateTime 付款结束时间
     * @param pageNum
     * @param pageSize
     * @return
     * @throws Exception
     */
    @Override
    public Paged<PaymentBizDto> getDepositPage(Map<String, Object> params, Integer pageNum, Integer pageSize) throws Exception {
        Paged<PaymentBizDto> result = new Paged<>(new ArrayList<>(), 0, pageSize);

        // 根据条件查询支付信息（订购支付）
        params.put("businessTypeList", Arrays.asList(PaymentBusinessTypeEnum.EXCLUSIVEL.getValue(),
                PaymentBusinessTypeEnum.SUBSCRIBE.getValue()));
        params.put("payType", PaymentCostTypeEnum.SUBSCRIBE.getValue());
        params.put("status", PaymentStatusEnum.SUCCESS_PAYMENT.getValue());
        Paged<PaymentDto> paymentDtoPage = paymentService.getPaymentPage(params, pageNum, pageSize);
        // 判断是否查询为空
        if (paymentDtoPage == null) {
            return result;
        } else if (paymentDtoPage.isEmpty()) {
            return result.setTotal(paymentDtoPage.getTotal()).setTab(paymentDtoPage.getTab());
        }

        result.setTotal(paymentDtoPage.getTotal()).setTab(paymentDtoPage.getTab());

        for (PaymentDto paymentDto : paymentDtoPage.getList()) {
            PaymentBizDto paymentBizDto = Convert.toPaymentBizDto(paymentDto);
            // 查询保证金信息，金额减去保证金
            PaymentDetailDto paymentDetailDto = paymentDetailService.getPaymentDetail(paymentDto.getId(),
                    PaymentDetailTypeEnum.DEPOSIT);
            if (paymentDetailDto != null) {
                paymentBizDto.setPayAmount(paymentDetailDto.getAmount());
            }
            result.getList().add(paymentBizDto);
        }
        return result;
    }

    /**
     * 用户支付记录
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public List<PaymentRecordBizDto> getPaymentRecord(Integer userId) {
        List<PaymentRecordBizDto> result = null;
        // 查询用户支付信息
        List<PaymentDto> paymentDtos = paymentService.getPaymentByUser(userId, PaymentStatusEnum.SUCCESS_PAYMENT);
        if (paymentDtos == null || paymentDtos.isEmpty()) {
            return result;
        }
        result = new ArrayList<>();
        for (PaymentDto paymentDto : paymentDtos) {
            PaymentRecordBizDto paymentRecordBizDto = Convert.toPaymentRecordBizDto(paymentDto);
            // 查询支付详情
            List<PaymentDetailDto> paymentDetailDtos = paymentDetailService.getPaymentDetail(paymentDto.getId());
            if (paymentDetailDtos == null) {
                continue;
            }
            Map<PaymentDetailTypeEnum, PaymentDetailBizDto> paymentDetailMap = new HashMap<>();
            List<PaymentDetailBizDto> paymentDetailBizDtos = Convert.toPaymentDetailBizDto(paymentDetailDtos);
            for (PaymentDetailBizDto paymentDetailBizDto : paymentDetailBizDtos) {
                paymentDetailMap.put(paymentDetailBizDto.getType(), paymentDetailBizDto);
            }
            paymentRecordBizDto.setPaymentDetailMap(paymentDetailMap);
            result.add(paymentRecordBizDto);
        }

        return result;
    }

    /**
     * 支付-预支付单
     *
     * @param createDto
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public String getOrderPay(PaymentBizCreateDto createDto) throws BizException, Exception {
        if ("dev".equalsIgnoreCase(PROFILES_ACTIVE) || "test".equalsIgnoreCase(PROFILES_ACTIVE)
                || "pre".equalsIgnoreCase(PROFILES_ACTIVE)) {
            // 开发、测试环境，支付金额1分
            createDto.setPayAmount(new BigDecimal("0.01"));
        }
        if (createDto.getCostType() == null) {
            throw new BizException("订单支付类型不能为空");
        }
        // 查询支付信息
        PaymentDto paymentDto = paymentService.getPaymentByOrder(createDto.getOrderCode(), createDto.getScheduleId(),
                createDto.getCostType());
        // 判断该订单是否存在待支付
        if (paymentDto != null) {
            if (PaymentStatusEnum.SUCCESS_PAYMENT.equals(paymentDto.getPayStatus())) {
                // 已支付
                logger.error("订单已支付,请勿重复支付({})", JSONObject.toJSONString(createDto));
                throw new BizException("订单已支付,请勿重复支付");
            } else if (PaymentStatusEnum.CLOSE.equals(paymentDto.getPayStatus())) {
                // 已关闭
                logger.error("订单已关闭,请勿支付({})", JSONObject.toJSONString(createDto));
                throw new BizException("订单已关闭,请勿支付");
            } else if (PaymentStatusEnum.FAIL_PAYMENT.equals(paymentDto.getPayStatus())) {
                // 支付失败的支付单，记录历史记录
                PaymentHistoryCreateDto historyCreateDto = Convert.toPaymentHistoryCreateDto(paymentDto);
                historyCreateDto.setExplanation("支付失败重新生成支付单");
                paymentHistoryService.create(historyCreateDto);
            } else {
                // 判断ip、金额、支付类型是否一致，是否在交易有效时间之内
                if (paymentDto.getPayWay() != null && createDto.getDeviceInfo().equals(paymentDto.getDeviceInfo())
                        && paymentDto.getPayAmount().equals(createDto.getPayAmount())
                        && paymentDto.getPayWay().equals(createDto.getPayWay())
                        && paymentDto.getTimeEnd().isAfter(LocalDateTime.now())) {
                    // 一致，直接返回预支付单信息
                    return paymentDto.getRequestData();
                }
                // 不一致，记录历史记录
                PaymentHistoryCreateDto historyCreateDto = Convert.toPaymentHistoryCreateDto(paymentDto);
                historyCreateDto.setExplanation("支付信息发生变化重新生成支付单");
                paymentHistoryService.create(historyCreateDto);
            }
        }
        PrepaymentDto prepaymentDto = null;
        // 不存在或不一致，调用相关第三方支付生成相应的预支付单
        if (createDto.getPayWay() == null || createDto.getPayWay().toString().startsWith("AIO_")) {
            // 智能终端支付
            prepaymentDto = aiopayOrderPay(createDto);
        } else if (createDto.getPayWay().toString().startsWith("WXPAY_")) {
            // 微信支付
            prepaymentDto = this.wechatpayOrderPay(createDto);
        } else if (createDto.getPayWay().toString().startsWith("ALPAY_")) {
            // 支付宝支付
            prepaymentDto = alipayOrderPay(createDto);
        } else if (createDto.getPayWay().toString().startsWith("UNIONPAY_")) {
            // 银联支付
            prepaymentDto = unionPayOrderPay(createDto);
        } else {
            logger.error("生成预支付单支付方式异常({})", JSONObject.toJSONString(createDto));
            throw new BizException("生成预支付单支付方式异常, 支付方式不存在");
        }
        // 保存或修改支付表
        if (paymentDto == null) {
            // 新增
            PaymentCreateDto paymentCreateDto = Convert.toPaymentCreateDto(createDto, prepaymentDto);
            Integer paymentId = paymentService.createPayment(paymentCreateDto);
            // 新增支付详情表
            List<PaymentDetailCreateDto> createDetais = Convert.toPaymentDetailCreateDto(createDto.getDetails(),
                    paymentId, paymentCreateDto.getOrderCode());
            paymentDetailService.createBatch(createDetais);
        } else {
            // 修改
            PaymentModifyDto paymentModifyDto = Convert.toPaymentModifyDto(createDto, prepaymentDto);
            paymentModifyDto.setPayStatus(PaymentStatusEnum.NO_PAYMENT);
            paymentModifyDto.setId(paymentDto.getId());
            paymentModifyDto.setRev(paymentDto.getRev());
            paymentService.modify(paymentModifyDto);
        }

        return prepaymentDto.getRequestData();
    }

    /**
     * 生成大屏支付预支付单
     *
     * @param createDto
     * @return
     */
    private PrepaymentDto aiopayOrderPay(PaymentBizCreateDto createDto) {
        PrepaymentDto aiopayDto = aiopayService.orderPay(createDto.getPayAmount());
        return aiopayDto;
    }

    /**
     * 生成银联支付预支付单
     *
     * @param createDto
     * @return
     */
    private PrepaymentDto unionPayOrderPay(PaymentBizCreateDto createDto) throws Exception {
        return unionpayService.orderPay(createDto);
    }

    /**
     * 生成支付宝预支付单
     *
     * @param createDto
     * @return
     * @throws Exception
     */
    private PrepaymentDto alipayOrderPay(PaymentBizCreateDto createDto) throws Exception {
        return alipayService.orderPay(Convert.toAlipayCreateDto(createDto));
    }

    /**
     * 生成微信支付预支付单
     *
     * @param createDto
     * @return
     * @throws Exception
     */
    private PrepaymentDto wechatpayOrderPay(PaymentBizCreateDto createDto) throws Exception {
        return wechatpayService.orderPay(Convert.toWechatpayCreateDto(createDto));
    }

    /**
     * 智能终端支付结果
     *
     * @param modifyDto
     * @return
     * @throws BizException
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public NotifyBizDto modifyAioResult(AioPayResultBizModifyDto modifyDto) throws BizException, Exception {
        NotifyBizDto result = Convert.toNotifyBizDto(modifyDto);
        // 查询支付单信息
        PaymentDto paymentDto = paymentService.getPayment(modifyDto.getPayNumber());
        if (paymentDto == null) {
            logger.error("付款流水号({})对应支付单信息不存在", modifyDto.getPayNumber());
            throw new BizException("付款流水号(" + modifyDto.getPayNumber() + ")对应支付单信息不存在");
        } else if (modifyDto.getPayAmount().compareTo(paymentDto.getPayAmount()) != 0) {
            logger.error("支付单金额({})和支付结果金额({})不一致", paymentDto.getPayAmount().multiply(new BigDecimal(100)),
                    modifyDto.getPayAmount());
            throw new BizException(
                    "支付单金额(" + paymentDto.getPayAmount() + ")和支付结果金额(" + modifyDto.getPayAmount() + ")不一致");
        }
        if (!aiopayService.payResult(Convert.toAioPayResultModifyDto(modifyDto, paymentDto))) {
            result.setPayResult(PaymentResultEnum.PAYERROR);
            return result;
        }
        paymentDto.setPayWay(modifyDto.getPayWay().getValue());
        modifyPayResult(paymentDto, result);

        return result;
    }

    /**
     * 支付回调修改
     *
     * @param notifyParam
     * @param paymentChannel
     * @return
     * @throws BizException
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public NotifyBizDto modifyNotify(Map<String, String> notifyParam, PaymentChannelEnum paymentChannel)
            throws BizException, Exception {
        NotifyBizDto result = null;
        BigDecimal notifyAmount = BigDecimal.ZERO;
        // 判断类型
        if (PaymentChannelEnum.WXPAY.equals(paymentChannel)) {
            // 微信支付
            result = modifyWechatpayNotify(notifyParam);
            notifyAmount = result.getPayAmount().divide(new BigDecimal(100));
        } else if (PaymentChannelEnum.ALIPAY.equals(paymentChannel)) {
            // 支付宝支付
            result = modifyAlipayNotify(notifyParam);
            if (PaymentResultEnum.FINISHED.equals(result.getPayResult())) {
                // 支付结束（支付宝会在支付成功3个月后发送该数据）
                return result;
            }
            notifyAmount = result.getPayAmount();
        } else if (PaymentChannelEnum.UNIONPAY.equals(paymentChannel)) {
            // 银联支付
            result = modifyUnionpayNotify(notifyParam);
            notifyAmount = result.getPayAmount().divide(new BigDecimal(100));
        }
        // 查询支付单信息
        PaymentDto paymentDto = paymentService.getPayment(result.getPayNumber());
        if (paymentDto == null) {
            // 判断支付结果是否支付成功
            if (PaymentResultEnum.SUCCESS.equals(result.getPayResult())) {
                logger.error("支付成功，付款流水号({})对应支付单信息不存在", result.getPayNumber());
                throw new BizException("支付成功，付款流水号(" + result.getPayNumber() + ")对应支付单信息不存在");
            } else {
                // 不是支付成功状态，则直接返回
                return result;
            }

        } else if (notifyAmount.compareTo(paymentDto.getPayAmount()) != 0) {
            logger.error("支付单金额({})和回调金额({})不一致", paymentDto.getPayAmount(), notifyAmount);
            throw new BizException(
                    "支付单金额(" + paymentDto.getPayAmount() + ")和回调金额(" + result.getPayAmount() + ")不一致");
        }

        return modifyPayResult(paymentDto, result);
    }

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public NotifyBizDto modifyPayResult(PaymentDto paymentDto, NotifyBizDto result) {
        if (!PaymentResultEnum.NOTPAY.equals(result.getPayResult())) {
            // 不是未支付，修改支付单状态
            paymentService.modifyPayResult(Convert.toPaymentModifyDto(paymentDto, result));
        }
        result.setOrderCode(paymentDto.getOrderCode());
        result.setBusinessType(paymentDto.getBusinessType());
        result.setCostType(paymentDto.getCostType());
        result.setUserId(paymentDto.getUserId());
        result.setPayWay(paymentDto.getPayWay());
        result.setScheduleId(paymentDto.getScheduleId());
        return result;
    }

    /**
     * 支付宝支付回调
     *
     * @param notifyData
     * @return
     * @throws Exception
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public NotifyBizDto modifyAlipayNotify(Map<String, String> notifyData) throws Exception {
        // 验证支付回调信息
        return Convert.toNotifyBizDto(alipayService.notifyPay(notifyData));
    }

    /**
     * 微信支付回调
     *
     * @param noifyParam
     * @return
     * @throws Exception
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public NotifyBizDto modifyWechatpayNotify(Map<String, String> noifyParam) throws Exception {
        // 验证支付回调信息
        WechatpayTradeTypeEnum tradeType = Enum.valueOf(WechatpayTradeTypeEnum.class, noifyParam.get("attach"));

        return Convert.toNotifyBizDto(wechatpayService.notifyPay(noifyParam.get("xmlStr"), tradeType));
    }

    /**
     * 银联支付回调
     *
     * @param noifyParam
     * @return
     * @throws Exception
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public NotifyBizDto modifyUnionpayNotify(Map<String, String> noifyParam) throws Exception {
        // 验证支付回调信息
        return Convert.toNotifyBizDto(unionpayService.notifyPay(noifyParam));
    }

    /**
     * 查询支付结果
     *
     * @param orderCode  订单号
     * @param scheduleId 排期id
     * @param costType   费用类型
     * @return
     * @throws BizException
     * @throws Exception
     */
    @Override
    public NotifyBizDto getPayResult(Long orderCode, Integer scheduleId, PaymentCostTypeEnum costType)
            throws BizException, Exception {
        NotifyBizDto result = null;
        // 查询支付单信息
        PaymentDto paymentDto = paymentService.getPaymentByOrder(orderCode, scheduleId, costType);
        if (paymentDto == null) {
            logger.error("查询支付结果支付单(orderCode:{}, scheduleId:{}, costType:{})信息不存在", orderCode, scheduleId, costType);
            throw new BizException("查询支付结果支付单(orderCode:" + orderCode + ", scheduleId:" + scheduleId + ", costType:"
                    + costType + ")信息不存在");
        } else if (PaymentStatusEnum.SUCCESS_PAYMENT.equals(paymentDto.getPayStatus())) {
            // 支付成功
            result = Convert.toNotifyBizDto(paymentDto);
            result.setPayResult(PaymentResultEnum.SUCCESS);
        } else if (PaymentStatusEnum.NO_PAYMENT.equals(paymentDto.getPayStatus())) {
            // 待支付，查询相关第三方支付结果
            if (paymentDto.getPayWay().toString().startsWith("WXPAY_")) {
                // 微信支付
                result = Convert.toNotifyBizDto(paymentDto);
                result.setPayResult(PaymentResultEnum.NOTPAY);
                // WechatpayResultDto wechatpayResultDto =
                // wechatpayService.orderQuery(paymentDto.getPayNumber(),
                // Convert.toWechatpayTradeTypeEnum(paymentDto.getPayWay()));
                // result.setPayTime(wechatpayResultDto.getTimeEnd());
                // result.setTransactionId(wechatpayResultDto.getTransactionId());
                // result.setPayResult(Convert.toPaymentResultEnum(wechatpayResultDto.getTradeState()));
            } else if (paymentDto.getPayWay().toString().startsWith("ALPAY_")) {
                // TODO 支付宝支付
                result = new NotifyBizDto();
                result.setPayResult(PaymentResultEnum.NOTPAY);
            } else if (paymentDto.getPayWay().toString().startsWith("UNIONPAY_")) {
                // 支付成功
                result = Convert.toNotifyBizDto(paymentDto);
                result.setPayResult(PaymentResultEnum.NOTPAY);
            }
            // 修改支付单信息
            result = modifyPayResult(paymentDto, result);
        } else if (PaymentStatusEnum.FAIL_PAYMENT.equals(paymentDto.getPayStatus())
                || PaymentStatusEnum.CLOSE.equals(paymentDto.getPayStatus())) {
            // 支付失败、支付关闭
            result = Convert.toNotifyBizDto(paymentDto);
            result.setPayResult(PaymentResultEnum.PAYERROR);
        }

        return result;
    }

    /**
     * 查询收款台账导出数据
     *
     * @param selectParams
     * @return
     */
    @Override
    public List<PaymentDownloadBizDto> getReceiptStandingBookDownload(Map<String, Object> selectParams) {
        List<PaymentDownloadBizDto> result = null;
        List<PaymentDto> payments = paymentService.getPaymentSuccessList(selectParams);
        if (payments == null || payments.isEmpty()) {
            return null;
        }
        result = new ArrayList<>();
        List<Integer> paymentIds = new ArrayList<>();
        for (PaymentDto payment : payments) {
            result.add(Convert.toPaymentDownloadBizDto(payment));
            paymentIds.add(payment.getId());
        }
        if (paymentIds.isEmpty()) {
            return result;
        }
        // 查询支付详情
        List<PaymentDetailDownloadDto> deposits = paymentDetailService.getPaymentDetailDownload(paymentIds);
        if (deposits == null || deposits.isEmpty()) {
            return result;
        }
        Map<Integer, PaymentDetailDownloadDto> depositsMap = deposits.stream()
                .collect(Collectors.toMap(PaymentDetailDownloadDto::getPaymentId, dto -> dto));
        for (PaymentDownloadBizDto paymentBiz : result) {
            PaymentDetailDownloadDto detail = depositsMap.get(paymentBiz.getPaymentId());
            if (detail != null) {
                BeanUtils.copyProperties(detail, paymentBiz);
            }
        }

        return result;
    }

    /**
     * 查询收款台账导出数据条数
     *
     * @param selectParams
     * @return
     */
    @Override
    public Long getReceiptStandingBookDownloadCount(Map<String, Object> selectParams) {
        if (selectParams == null) {
            selectParams = new HashMap<>(0);
        }
        return paymentService.getPaymentSuccessListCount(selectParams);
    }
}

